package prv.pursuivant;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;

import prv.pursuivant.armory.Importer;
import prv.pursuivant.armory.impl.ArmoryModule;
import prv.pursuivant.config.CategorySerializer;
import prv.pursuivant.config.Config;
import prv.pursuivant.config.ConfigSerializer;
import prv.pursuivant.config.ImporterDesc;
import prv.pursuivant.config.impl.XStreamCategorySerializerModule;
import prv.pursuivant.config.impl.XStreamConfigSerializerModule;
import prv.pursuivant.core.AchievTypesTree;
import prv.pursuivant.core.AllAchievements;
import prv.pursuivant.render.Destination;
import prv.pursuivant.render.ModelRenderer;
import prv.pursuivant.render.html.HtmlRendererModule;
import prv.pursuivant.render.impl.MultipleFilesDestination;
import prv.pursuivant.util.URLUtil;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;

public class ConsoleRunner {

	@SuppressWarnings("unused")
	private final String[] args;

	public ConsoleRunner(String[] args) {
		this.args = args;
	}

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		new ConsoleRunner(args).run();
	}

	public void run() throws IOException {
		Config config = readConfig();
		AchievTypesTree category = readAchievTree(config);
		Importer importer = getImporter(config.getImporterDesc(), config
				.getActiveCategory().getId());
		AllAchievements achievements = importer.readAllAchievements(config
				.getToons());
		Destination destination = new MultipleFilesDestination("renders", new URLUtil());
		ModelRenderer renderer = Guice.createInjector(
				new HtmlRendererModule(destination, config.getActiveAchievements(), config.getToons(), category, achievements))
				.getInstance(ModelRenderer.class);
		renderer.renderModel(new Date());
	}

	private AchievTypesTree readAchievTree(Config config) throws IOException {
		CategorySerializer categorySerializer = Guice.createInjector(
				new XStreamCategorySerializerModule()).getInstance(
				CategorySerializer.class);
		final FileInputStream categoryStream = new FileInputStream(
				"config/category." + config.getActiveCategory().getId()
						+ ".xml");
		AchievTypesTree category = categorySerializer.readTree(categoryStream);
		categoryStream.close();
		return category;
	}

	public Config readConfig() throws IOException {
		ConfigSerializer configSerializer = Guice.createInjector(
				new XStreamConfigSerializerModule()).getInstance(
				ConfigSerializer.class);
		final FileInputStream configStream = new FileInputStream(
				"config/config.xml");
		Config config = configSerializer.readConfig(configStream);
		configStream.close();
		return config;
	}

	public Importer getImporter(final ImporterDesc importerDesc,
			final String categoryId) throws IOException {
		AbstractModule additionalModule = new AbstractModule() {
			@Override
			protected void configure() {
				bind(ImporterDesc.class).toInstance(importerDesc);
				bind(String.class).annotatedWith(Names.named("categoryId"))
						.toInstance(categoryId);
			}
		};
		Injector injector = Guice.createInjector(new ArmoryModule(),
				additionalModule);
		Importer importer = injector.getInstance(Importer.class);
		return importer;
	}

}
